package com.brillilab.service.core.elsearch.impl;

import com.brillilab.domain.pa.kit.SampleSearchPa;
import com.brillilab.domain.po.elsearch.EsGlobalSample;
import com.brillilab.domain.po.elsearch.EsSampleAttr;
import com.brillilab.elsearch.constants.ElsearchConfig;
import com.brillilab.elsearch.reponsitories.EsGlobalSampleRepository;
import com.brillilab.elsearch.utils.ElsearchUtils;
import com.brillilab.service.core.elsearch.IEsGlobalSampleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

@Service
@Slf4j
public class EsGlobalSampleServiceImpl implements IEsGlobalSampleService {

    @Resource
    private EsGlobalSampleRepository esGlobalSampleRepository;
    @Autowired
    private ElsearchConfig elsearchConfig;

    @Override
    public Page<EsGlobalSample> queryList(SampleSearchPa pa) {
        List<Long> reagentTypeIds = pa.getReagentTypeIds();
        String searchName=pa.getSearchName();
        Long reagentTypeId=pa.getReagentTypeId();
        Integer zone=pa.getZone();
        List<EsSampleAttr> sampleAttr=pa.getSampleAttr();


        Pageable pageable=PageRequest.of(((int) pa.getPageNum() - 1) >= 0 ? (int) pa.getPageNum() - 1 : 1,
                (int) pa.getPageSize() > 0 ? (int) pa.getPageSize() : 10);

        BoolQueryBuilder builder=QueryBuilders.boolQuery();
        builder.must(QueryBuilders.termQuery("isDelete",0));

        if(reagentTypeId != null){
            builder.must(QueryBuilders.termQuery("reagentTypeId",reagentTypeId));
        }

        if(!CollectionUtils.isEmpty(reagentTypeIds)){
            builder.must(QueryBuilders.termsQuery("reagentTypeId",reagentTypeIds));
        }

        if(zone != null){
            builder.must(QueryBuilders.termQuery("zone",zone));
        }

        if(StringUtils.isNotBlank(searchName)){
            searchName=searchName.trim();
            builder.must(QueryBuilders.boolQuery()
                    .should(QueryBuilders.boolQuery().should(QueryBuilders.matchPhrasePrefixQuery("kitName",searchName)
                            .analyzer(elsearchConfig.getChineseAnalyzer()).boost(elsearchConfig.getPhrasePrefixBoost()))
                            .should(QueryBuilders.matchPhraseQuery("kitName",searchName)
                                    .analyzer(elsearchConfig.getChineseAnalyzer()).slop(1)
                                    .boost(elsearchConfig.getPhrasePrefixBoost()))
                            .should(QueryBuilders.matchQuery("kitName",searchName)
                                    .analyzer(elsearchConfig.getChineseAnalyzer()).operator(Operator.AND)
                                    .boost(elsearchConfig.getMatchAndBoost()))
                            .boost(5)))
                    .boost(5);
        }

        if(!CollectionUtils.isEmpty(sampleAttr)){
            sampleAttr.forEach(attr -> {
                if(attr.getSampleTemplateId() != null && StringUtils.isNotBlank(attr.getAttrValue())){
                    QueryBuilder attrQuery=QueryBuilders.nestedQuery("sampleAttr",
                            QueryBuilders.boolQuery()
                                    .must(QueryBuilders.termQuery("sampleAttr.sampleTemplateId",attr.getSampleTemplateId()))
                                    .must(QueryBuilders.boolQuery()
                                            .should(QueryBuilders.matchQuery("sampleAttr.attrValue",attr.getAttrValue()))
                                            .should(QueryBuilders.termQuery("sampleAttr.attrValue.keyword",attr.getAttrValue()))
                                            .should(QueryBuilders.wildcardQuery("sampleAttr.attrValue.keyword",ElsearchUtils.getWildCardQauryValue(attr.getAttrValue())))
                                    ),ScoreMode.Total);
                    builder.must(attrQuery);
                }
            });
        }

        return esGlobalSampleRepository.search(builder,pageable);
    }
}
